﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using FaceSharp.Api.GraphApi;
using FaceSharp.Api.Types;
using Newtonsoft.Json.Linq;

namespace FaceSharp.Api.Objects
{
    public class Groups : GraphBase
    {
        private readonly IFacebookCore _facebookCore;

        public Groups(IFacebookCore facebookCore): base(facebookCore)
        {
            _facebookCore = facebookCore;
        }

        public IEnumerable<Types.Group> List(string objectId)
        {
            Trace.Write("Begin Request", "Facebook.Objects.Group.List");            
            var jObject = MakeGraphRequest(objectId,"groups");

            var groups = new List<Types.Group>();
            if (jObject != null)
            {
                var jData = (JArray)jObject["data"];
                groups = (from fbGroup in jData
                          select ParseGroup(fbGroup)
                         ).ToList();
            }
            Trace.Write("End Request", "Facebook.Objects.Group.List");
            return groups;
        }

        public IEnumerable<Types.User> GetMembers(string objectId)
        {
            Trace.Write("Begin Request", "Facebook.Objects.Group.GetMembers");
            var jObject = MakeGraphRequest(objectId, "members");

            var groupsMembers = new List<Types.User>();
            if (jObject != null)
            {
                var jData = (JArray)jObject["data"];
                groupsMembers = (from fbUser in jData
                          select ParseUser(fbUser)
                         ).ToList();
            }
            Trace.Write("End Request", "Facebook.Objects.Group.GetMembers");
            return groupsMembers;            
        }

        public Types.Group Get(long groupdId)
        {
            Trace.Write("Begin Request", "Facebook.Objects.Group.Get");
            var jObject = MakeGraphRequest(groupdId.ToString());
            var fbgroup = ParseGroup(jObject);
            Trace.Write("End Request", "Facebook.Objects.Group.Get");
            return fbgroup;
        }



        private static DateTime? ParseDateTime(JToken jToken, string key)
        {
            DateTime? returnVal = null;
            DateTime tempVal;
            if (jToken[key] != null && DateTime.TryParse((string)jToken[key], out tempVal))
            {
                returnVal = tempVal;
            }
            return returnVal;
        }

        private static Types.Group ParseGroup(JToken jObject)
        {
            Trace.Write("Begin Request", "Facebook.Objects.Group.ParseGroup");

            var fbgroup = new Types.Group();
            if (jObject != null)
            {
                Trace.Write("JSONData:" + jObject.ToString(), "Facebook.Objects.Group.ParseGroup");

                fbgroup = new Types.Group()
                {
                    Id = long.Parse((string)jObject["id"]),
                    Name = (string)jObject["name"] ?? "",
                    Description = (string)jObject["description"] ?? "",
                    Privacy = (string)jObject["privacy"] ?? "",
                    UpdatedTime = ParseDateTime(jObject, "updated_time"),
                };

                var owner = (JObject)jObject["owner"];
                if (owner != null)
                {
                    fbgroup.Owner = new Types.Group.OwnerData()
                    {
                        Id = long.Parse((string)owner["id"]),
                        Name = (string)owner["name"]
                    };
                }
                else
                {
                    fbgroup.Owner = new Types.Group.OwnerData();
                }

                var venue = (JObject)jObject["venue"];
                
                if (venue != null)
                {
                    fbgroup.Venue = new Types.Group.VenueData()
                    {
                        Street = venue["street"] == null ? string.Empty : (string)venue["street"],
                        City = venue["city"] == null ? string.Empty : (string)venue["city"],
                        State = venue["state"] == null ? string.Empty : (string)venue["state"],
                        Country = venue["country"] == null ? string.Empty : (string)venue["country"],
                        Latitude = venue["latitude"] == null ? string.Empty : venue["latitude"].ToString(),
                        Longitude = venue["longitude"] == null ? string.Empty : venue["longitude"].ToString()
                    };
                }
                else
                {
                    fbgroup.Venue = new Types.Group.VenueData();
                }
            }
            return fbgroup;
        }

        private static Types.User ParseUser(JToken jObject)
        {
            Trace.Write("Begin Request", "Facebook.Objects.Group.ParseUser");

            var fbuser = new Types.User();
            if (jObject != null)
            {
                Trace.Write("JSONData:" + jObject.ToString(), "Facebook.Objects.Group.ParseUser");

                fbuser = new Types.User()
                {
                    Id = long.Parse((string)jObject["id"]),
                    Name = (string)jObject["name"] ?? ""
                };
            }
            return fbuser;            
        }
    }
}
